<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Discuz! 用户使用说明书 - 高级应用</title><link rel="stylesheet" href="discuz_guide.css">
<base target="_blank">
</head>

<body leftmargin="0" rightmargin="0" topmargin="0">
<script language="JavaScript" src="header.js"></script>

<table width="100%" cellpadding="0" cellspacing="0" border="0">

<tr><td class="title">本栏目下相关链接</td></tr>
<tr><td><br /><ul><script language="JavaScript" src="advanced.js"></script></ul><br /></td></tr>

<tr><td class="title">MySQL 备份、优化与故障处理<a name="title"></a></td></tr>
<tr><td><br />
<p>MySQL 是一种高效快速的中小型数据库系统，这套系统的读写速度，尤其是读速度可以媲美和超过很多昂贵的商业数据库系统，同时其功能
也完全可以满足一般网络应用软件的需要，适合为论坛等软件构建的数据库支撑环境。Discuz! 的 MySQL 版本充分可以充分发挥该数据库软件
的优势，更加优化的进行数据库操作，最大限度的保证了系统的稳定。然而，在实际使用中，为了使得数据库服务器运行在最佳状态，您可能
仍然需要做一些优化，或在故障时进行必要的维修操作。本文将对 MySQL 系统的日常使用、常规优化方案和故障恢复作以简要说明。

<br /><br /><br /></td></tr><tr><td class="title">数据备份与恢复</td></tr>
<tr><td><br />
<p class="subtitle">最快的备份方法：直接文件复制<ul>
<p>MySQL 的数据库文件支持直接复制（Hot-copy），您在任意类型操作系统的服务器中将数据文件复制下来，拷贝到另外的一台服务器的 MySQL
数据目录，只要数据库软件版本不相差太多（例如不是 3.22 和 3.23/4.0），您可以立即直接使用复制过来的完整数据文件。基于这种特性您可以
使用最短的时间完成数据备份。

<p>按照常见的安装习惯，Unix 版本的 MySQL 数据目录通常可能为（不限于下列）：
<p><ul>
<li>/var/lib/mysql/
<li>/usr/local/mysql/data/
<li>/usr/local/mysql/var/
</ul>

<p>Windows 版本的 MySQL 数据目录通常可能为（不限于下列）：
<p><ul>
<li>c:\mysql\data\
<li>d:\mysql\data\
<li>x:\mysql\data\
</ul>

<p>在数据目录下，可能有多个以数据库名命名的子目录，将

<p>建议您在直接复制（Hot-copy）的时候尽量把数据库服务器停止，这样备份的数据会较少出错。如果不方便停止服务器，又恰好在某一文件
的某一部分上，备份和数据库服务器写入同时进行，则可能造成拷贝下来的数据文件存在错误。但这种错误通常不致命，可以经过修复而恢复，
修复的方法将在后面的部分作以说明。

<p>如果需要恢复某些数据表，只需先把数据库停止，把备份的文件拷贝到原有的目录中覆盖即可。注意在 Unix 系统中，需要检查覆盖后的
文件属性和属主，以免无法被 MySQL 读取而报错。

<p><b>本方法只适合拥有独立服务器的用户使用，虚拟主机用户不在此列。</b>

</ul><p class="subtitle">较快而安全的备份方法：mysqldump<ul>
<p>MySQL 软件本身提供了将数据内容导出为 SQL 文件的工具－－mysqldump。通过这一方法备份和恢复，较直接文件复制来说更为安全，但速度
慢一些，数据表大则更是如此。

<p>您可以在 MySQL 程序文件目录找到备份使用的工具 mysqldump 及恢复使用的工具 mysql。按照常见的安装习惯，Unix 版本的 MySQL 程序
文件目录通常可能为（不限于下列）：
<p><ul>
<li>/usr/bin/
<li>/usr/local/mysql/bin/
</ul>

<p>Windows 版本的 MySQL 程序文件目录通常可能为（不限于下列）：
<p><ul>
<li>c:\mysql\bin\
<li>d:\mysql\bin\
<li>x:\mysql\bin\
</ul>

<p>备份和恢复的命令分别为（其中斜体字表示需要替换相关的内容）：
<p><ul>
<li>备份：mysqldump --force --add-drop-table --extended-insert -h"<i>数据库主机名</i>" -u"<i>用户名</i>" -p"<i>密码</i>" "<i>数据库名</i>" > <i>备份数据文件名</i>
<li>恢复：mysql -h"<i>数据库主机名</i>" -u"<i>用户名</i>" -p"<i>密码</i>" "<i>数据库名</i>" < <i>备份数据文件名</i>
</ul>

<p>Discuz! 在系统设置中已经设计了此种备份模式（Shell 方式），速度与直接在服务器终端操作是完全一致的，但不需要记忆命令与参数，
只需通过 web 界面修改操作即可。此功能需要备份出，和恢复到的服务器上的 PHP 具有 Shell 权限，您可以尝试一下即知。

</ul><p class="subtitle">兼容性最好的备份方法：Discuz! 分卷备份<ul>
<p>早在 Discuz! 的初期版本就率先在论坛软件中内置了支持大量数据备份与恢复的分卷备份功能，此种方法虽然速度最慢，但具有良好的
兼容性，可以在几乎所有服务器环境，包括虚拟主机环境成功的备份大量数据。

<p>分卷备份的使用简单，您只需在 Discuz! 系统设置中选择分卷备份，按照提示进行即可。

<p><b>在进行数据恢复时，尤其是将备份的数据恢复到另外的服务器、或另外的数据库中时，您需要事先安装一个与备份数据版本相同的空论坛，
确保该空论坛使用和备份数据中相同的数据表前缀（即 config.inc.php 中的 $tablepre 设置），同时在设置管理员时，使用与备份数据中相同的
一个管理员用户名、密码和安全提问，这样才能保证分卷备份数据的导入连贯和成功。</b>

<p>导入前，把备份数据文件完整的上传到服务器论坛目录中的 ./forumdata 下，在 系统设置 的 数据库恢复 功能中选择第一卷的文件名，点
导入链接，之后相关的分卷数据会被自动导入。

<p>同时我们提供了一个数据库恢复程序，详情请见《<a href="advanced_tools.htm" target="_blank">Discuz!工具箱</a>》里面的数据恢复工具。

</ul><br /></td></tr><tr><td class="title">常规优化方案</td></tr>
<tr><td><br />
<p class="subtitle">建议使用的版本<ul>
<p>通常情况下，Unix 类操作系统用户可以直接使用 MySQL 官方提供的已经编译好的软件包，可以避免可能的兼容性问题。如果对一些特殊参数
有要求，也可以自行编译源码，但仅建议有丰富经验的用户使用，如果发现有不稳定或不兼容现象，请检查相关的编译参数是否存在问题。

<p>目前我们建议使用的 MySQL 版本为 4.0.x 版，相对 3.23 系列，4.0.x 同样稳定和安全，不仅提供了更多的功能、更好的兼容性，而且修复
了很多 3.23 系列的 BUG。在 Windows 系统中，请使用 mysqld-nt（NT/2000/2003 系统）作为服务器，mysqld-max-nt 只有在需要用到 bdb 等
功能的时候才需要。

</ul><p class="subtitle">数据库的常规优化<ul>
<p>MySQL 本身的配置文件 my.cnf（或 my.ini）中的相关参数，对整个数据库系统来说尤为重要。针对不同的服务器内存容量，MySQL 程序包
中提供了 my-small.cnf、my-medium.cnf、my-large.cnf、my-huge.cnf 四个分别适用于服务器内存不低于 64M、256M、512M、1G 情况下的参数
设置，您可以根据自身机器的实际情况，数据库应用所占比重，在上述四个文件中提供的参数基础上对配置文件进行修改。Unix 类系统用户，
建议将配置文件命名为 my.cnf 放置于 /etc 中。Windows 系统用户直接在 Winmysqladmin.exe 中对 my.ini 进行修改即可。

<p>除了以上默认的配置文件提供的参数以外，通常情况您还需要在 [mysqld] 后修改或增加以下的参数以适应大部分 web 应用程序的需要：
<p><ul>
<li>最大连接数为 600，以满足一般应用对连接数的需要：增加 max_connections = 600。根据我们的经验，500～1000 是较为合适的数值，没
必要将其设置为超过 1000，那只会造成对资源的浪费。
<li>不使用 innodb 和 bdb：增加两行内容，分别是 skip-innodb 和 skip-bdb。Discuz! 和大部分 web 应用程序不需要使用此两项功能，因此
将其关闭以节约内存和磁盘空间，提高效率。
<li>连接超时时间 5，避免空闲进程过多的内存占用：增加 wait_timeout = 5。通过减少超时时间，使得使用 pconnect（长期连接）的用户在
利用其不需反复验证用户名和密码的同时，避免打开过多的空闲进程，减少内存消耗。
<li>禁止端口连接：增加 skip-networking。如果使用 Unix 类操作系统，数据库和 httpd 在同一台服务器，且不需要远程读取数据库，可增设
此项参数，关闭默认的 3306 端口，有效提禁止外部网络未经授权的访问，避免端口被用以进行 DDoS 攻击。Windows 系统不需要（不能）增加
这个参数。
</ul>

<p>其他参数的配置在此不详述，如果您对服务器及 MySQL 数据库有相当的了解，可以通过数据库的日常运行情况，有针对性的进行修改。

</ul><p class="subtitle">数据表优化（Optimize Table）<ul>
<p>当您的库中删除了大量的数据后，您可能会发现数据文件尺寸并没有减小。这是因为删除操作后在数据文件中留下碎片所致。Discuz! 在
系统数设置界面提供了数据表优化的功能，可以去除删除操作后留下的数据文件碎片，减小文件尺寸，加快未来的读写操作。您只要在做完
批量删除，或定期（如每一两个月）进行一次数据表优化操作即可。

</ul><br /></td></tr><tr><td class="title">故障解决办法</td></tr>
<tr><td><br />
<p>
<p>由于 MySQL 本身的读写及锁定机制等方面的原因，与一些其他数据库软件一样，在特殊情况下的极为频繁读写时，或在服务器掉电、死机等
情况下，相关的数据文件可能会发生被损坏的情况，通常可以采用以下的方式加以解决。

<p class="subtitle">Discuz!修复工具<ul>
<p>可以使用Discuz!工具箱里面修复数据表工具进行修复，详情请见《<a href="advanced_tools.htm" target="_blank">Discuz!工具箱</a>》。

<p>这个工具能修复大多数常见的数据库错误，尤其是错误号为 126、127 的错误，对 145 错误也可修复，同时能对数据表在修复之后进行优化。
如果一次修复不成功，可以尝试多次，或将数据库重启后再试。

</ul><p class="subtitle">myisamchk 修复工具<ul>
<p>MySQL 自带了专门用户数据表检查和修复的工具－－myisamchk，当 repair.php 多次修复均无法成功时，可以在服务器终端使用 myisamchk
进行修复。在 MySQL 的程序文件目录（见《数据备份与恢复》中的说明）可以找到这个工具。

<p>常用的修复命令为 myisamchk -r 数据文件目录/数据表名.MYI，如果 -r 参数不能奏效，可以先把数据文件备份（备份可使用直接文件复制
的方式，详见《数据备份与恢复》中的说明）后使用 -o 参数。

<p>另外 MySQL 官方文档中还提供了针对上面操作均无法奏效时的特殊办法，如先清空重建数据表，然后再用备份的数据文件覆盖等，这种特别
复杂的情况用户通常不会碰到，因此这里不再做过于深入的研究。

</ul><p class="subtitle">数据表经常性损坏的解决方法<ul>
<p>首先请确认在服务器硬件不存在问题（如内存工作不稳定、散热条件不好等），且使用中的操作系统版本也没有相关的 BUG 报告或升级补丁。
这种情况下，如果数据库仍出现经常性的损坏，请检查是否 MySQL 的编译方式或参数存在问题。通常情况下使用官方提供的编译好的版本是比较
稳定的，可以长期使用。如果您钟爱自行编译相关程序，请确认您的语言编译器（如 gcc）和配置的相关参数没有导致不稳定的因素。同时，磁盘
分区满也可能是导致数据表经常性损坏的原因。网上提供了一些问题的处理方法（英文），需要时可多参考，并针对您的具体服务器环境制定解决
方案。

</ul></td></tr></table>

<script language="JavaScript" src="footer.js"></script>
</body>
</html>
